home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / tpref.exe / TPR3B.TXT < prev    next >
Text File  |  1992-10-19  |  63KB  |  1,625 lines

  1.                    Chapter 3
  2.                  - continued -
  3.                  - Part 2 of 3 parts -
  4.                                     of the
  5.                             Turbo Pascal Reference
  6.  
  7.                            The Turbo Pascal Language
  8.  
  9.  
  10. This chapter is part of the Turbo Pascal Reference electronic freeware book (C)
  11. Copyright 1992 by Ed Mitchell.  This freeware book contains supplementary
  12. material to Borland Pascal Developer's Guide, published by Que Corporation,
  13. 1992.  However, Que Corporation has no affiliation with nor responsibility for
  14. the content of this free book.  Please see Chapter 1 of the Turbo Pascal
  15. Reference for important information about your right to distribute and use this
  16. material freely.  If you find this material of use, I would appreciate your
  17. purchase of one my books, such as the Borland Pascal Developer's Guide or
  18. Secrets of the Borland C++ Masters, Sams Books, 1992.  Thank you.
  19.  
  20.  
  21. Pointers and Complex Data Structures
  22.      Turbo Pascal provides a large variety of built-in data types.  However, to
  23. create specific data structures such as list, queues, stacks, trees and so on,
  24. requires that you create and maintain the appropriate data structures yourself.
  25. Pointers are used extensively to create these types of data structures.
  26.      Figure 3.4 illustrates a list structure containing a list of filenames. 
  27. Each filename is stored in a record, together with pointers to the next and
  28. previous items in the list. 
  29.  
  30. ***03tpr04.pcx***
  31. Figure 3.4.  Pointers are often used in record structures to create list data
  32. structures, as shown here.  In a list, each element is linked, via a pointer,
  33. to another element in the list.
  34.  
  35.      Such a list structure is represented as a Pascal record, containing space
  36. for the filename and other information, plus pointer values to the next and
  37. previous list entries.  Listing 3.6 shows a sample data record declared as the
  38. type TListEntry.  A pointer to TListEntry is defined as PListEntry.
  39.  
  40.  
  41. Listing 3.6.  A sample data record set up for use in a list data structure. 
  42. Note the use of the separate PListEntry, defined as a pointer to TListEntry.
  43.  
  44. type
  45.      { Data record to create the list structure }
  46.      PListEntry = ^TListEntry;
  47.      TListEntry = record
  48.        DirInfo : SearchRec;
  49.        Next    : PListEntry;
  50.        Previous: PListEntry;
  51.      end; {TListEntry}
  52.  
  53. A list is constructed out of these records by creating a pointer to the first
  54. item in the list, and storing the first pointer in a variable called ListHead,
  55. and using New ( PListEntry ) to create each entry.   The variable ListTail
  56. points to the last item in the list.
  57.  
  58.      var
  59.        ListHead : PListEntry;
  60.        ListTail : PListEntry;
  61.  
  62.      The Next field of the TListEntry record is used to point to the next
  63. succeeding item in the list.  Each time an item is added to the list, the
  64. previous item's Next field is set to point to the new item, and the new item's
  65. Next field, if its the last item in the list, is set to nil to mark the end of
  66. the list.
  67.      The Previous field is used to link the list of items in both directions. 
  68. In this way, the items in the list can be accessed in both the forward and the
  69. backwards directions.
  70.      Listing 3.7 presents a complete sample list program that reads the names
  71. of the files from the current subdirectory and places them into a list data
  72. structure.  The program then displays the list in both the forward and backward
  73. directions, using the Next or Previous pointer to reach the next or previous
  74. element in the list structure.
  75.  
  76. Listing 3.7.  This program uses pointers to create and manipulate a list data
  77. structure.  
  78.    1  program DemoList;
  79.    2  {
  80.    3  Demonstrates the use of pointers to create a list structure, demonstrates
  81. how
  82.    4  list traversal is done in both forwards and backwards directions, and
  83. provides
  84.    5  routines to add (or insert) and delete items in the list.
  85.    6  
  86.    7  You can modify these routines for use as a general purpose list
  87. manipulation
  88.    8  tool, by changing the ListEntry data structure to hold other types of
  89. data.
  90.    9  
  91.   10  This demonstration program uses the Dos library routines FindFirst and
  92.   11  FindNext to read the default file subdirectory.
  93.   12  }
  94.   13  uses  Dos;
  95.   14  
  96.   15  type
  97.   16    { Data record to create the list structure }
  98.   17    PListEntry = ^TListEntry;
  99.   18    TListEntry = record
  100.   19      DirInfo : SearchRec;
  101.   20      Next    : PListEntry;
  102.   21      Previous: PListEntry;
  103.   22    end; {TListEntry}
  104.   23  
  105.   24  var
  106.   25    ListHead : PListEntry;
  107.   26    ListTail : PListEntry;
  108.   27  
  109.   28  
  110.   29  function LowerCase (S : String ) : String;
  111.   30  Var
  112.   31    I : Integer;
  113.   32  begin
  114.   33    for I := 1 to length(s)  do
  115.   34      if ((S[I]>='A') and (S[I]<='Z'))  then
  116.   35        S[I] :=  Chr( Ord( S[I] ) + 32 );
  117.   36    LowerCase := S;
  118.   37  end;
  119.   38  
  120.   39  
  121.   40  
  122.   41  procedure InitDirectoryList;
  123.   42  { Initialize the directory list structure.
  124.   43    For convenience, the first entry contains the default volumne name C:\.
  125.   44  }
  126.   45  begin
  127.   46    ListHead := New(PListEntry);
  128.   47    ListHead^.Next := NIL;
  129.   48    ListHead^.Previous := NIL;
  130.   49    ListTail := ListHead;
  131.   50    ListHead^.DirInfo.Name := 'C:\';
  132.   51  end; {InitDirectoryList}
  133.   52  
  134.   53  
  135.   54  
  136.   55  function  AddEntry (     Location : PListEntry;
  137.   56                       Var ListEntry : SearchRec ) : PListEntry;
  138.   57  Var
  139.   58    NewEntry  : PListEntry;
  140.   59    SavedNext : PListEntry;
  141.   60  
  142.   61  begin
  143.   62    NewEntry := New ( PListEntry );
  144.   63    NewEntry^.DirInfo := ListEntry;
  145.   64  
  146.   65    If  Location = ListTail  Then
  147.   66    {Adding an item on to the tail of the list}
  148.   67    begin
  149.   68      NewEntry^.Next := NIL;
  150.   69      NewEntry^.Previous := ListTail;
  151.   70      ListTail^.Next := NewEntry;
  152.   71      ListTail := NewEntry;
  153.   72    end
  154.   73    else
  155.   74    {inserting an item within the list}
  156.   75    begin
  157.   76      SavedNext := Location^.Next;
  158.   77      Location^.Next := NewEntry;
  159.   78  
  160.   79      NewEntry^.Next := SavedNext;
  161.   80      NewEntry^.Previous := Location;
  162.   81  
  163.   82      SavedNext^.Previous := NewEntry;
  164.   83      
  165.   84    end;{begin}
  166.   85  
  167.   86    AddEntry := NewEntry;
  168.   87  
  169.   88  end;{AddEntry}
  170.   89  
  171.   90  
  172.   91  
  173.   92  function  RemoveEntry ( Location : PListEntry;
  174.   93                          HowMany  : Integer ) : PListEntry;
  175.   94  
  176.   95  { Starting at the point in the list indicated by 'Location', delete
  177.   96    'HomeMany' entries from the list.
  178.   97    Return:  A pointer to the first item after those that were deleted.
  179.   98  }
  180.   99  
  181.  100  var
  182.  101    CountOfItems : Integer;
  183.  102  
  184.  103    function DeleteEntry ( Location : PListEntry ) : PListEntry;
  185.  104    begin
  186.  105      if  Location <> NIL  then
  187.  106      begin
  188.  107        If  Location^.Previous <> NIL  Then
  189.  108          Location^.Previous^.Next := Location^.Next;
  190.  109        If  Location^.Next <> NIL  Then
  191.  110          Location^.Next^.Previous := Location^.Previous;
  192.  111        DeleteEntry := Location^.Next;
  193.  112        If  Location = ListTail  Then
  194.  113          ListTail := Location^.Previous;
  195.  114        Dispose(Location);
  196.  115      end
  197.  116      else
  198.  117        DeleteEntry := NIL;
  199.  118    end;
  200.  119  
  201.  120  begin {RemoveEntry}
  202.  121    For  CountOfItems := 1 to HowMany Do
  203.  122      Location := DeleteEntry ( Location );
  204.  123    RemoveEntry := Location;
  205.  124  end;{RemoveEntry}
  206.  125  
  207.  126  
  208.  127  function Move_Fwd ( Location : PListEntry;
  209.  128                      HowFar : Integer ) : PListEntry;
  210.  129  {Starting from 'location' move ahead 'HowFar' items in the list
  211.  130   and return the new location
  212.  131  }
  213.  132  Var
  214.  133    I : Integer;
  215.  134  begin
  216.  135    For  I := 1 to HowFar  Do
  217.  136      If  Location^.Next <> NIL  Then
  218.  137        Location := Location^.Next;
  219.  138    Move_Fwd := Location;
  220.  139  end;{Move_Fwd}
  221.  140  
  222.  141  
  223.  142  function Move_Bwd ( Location : PListEntry;
  224.  143                      HowFar : Integer ) : PListEntry;
  225.  144  {Starting from 'location' move backwards 'HowFar' items in t